home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / emula / arosdv19.lha / AROS / exec / allocsignal.c < prev    next >
C/C++ Source or Header  |  1996-10-24  |  3KB  |  130 lines

  1. /*
  2.     (C) 1995-96 AROS - The Amiga Replacement OS
  3.     $Id: allocsignal.c,v 1.5 1996/10/24 15:50:44 aros Exp $
  4.     $Log: allocsignal.c,v $
  5.     Revision 1.5  1996/10/24 15:50:44  aros
  6.     Use the official AROS macros over the __AROS versions.
  7.  
  8.     Revision 1.4  1996/08/13 13:55:58  digulla
  9.     Replaced AROS_LA by AROS_LHA
  10.     Replaced some AROS_LH*I by AROS_LH*
  11.     Sorted and added includes
  12.  
  13.     Revision 1.3  1996/08/01 17:41:05  digulla
  14.     Added standard header for all files
  15.  
  16.     Desc:
  17.     Lang:
  18. */
  19. #include <exec/execbase.h>
  20. #include <exec/tasks.h>
  21. #include <aros/libcall.h>
  22.  
  23. /*****************************************************************************
  24.  
  25.     NAME */
  26.     #include <clib/exec_protos.h>
  27.  
  28. AROS_LH1(BYTE, AllocSignal,
  29.  
  30. /*  SYNOPSIS */
  31.     AROS_LHA(LONG, signalNum, D0),
  32.  
  33. /*  LOCATION */
  34.     struct ExecBase *, SysBase, 55, Exec)
  35.  
  36. /*  FUNCTION
  37.     Allocate a given signal out of the current task's pool of signals.
  38.     Every task has a set of signals to communicate with other tasks.
  39.     Half of them are reserved for the system and half of them is
  40.     free for general use. Some of the reserved signals (e.g.
  41.     SIGBREAKF_CTRL_C) have a defined behaviour and may be used by user
  42.     code, however.
  43.  
  44.     INPUTS
  45.     signalNum - Number of the signal to allocate or -1 if any signal
  46.             will do.
  47.  
  48.     RESULT
  49.     Number of the signal or -1 if the signal couldn't be allocated.
  50.  
  51.     NOTES
  52.  
  53.     EXAMPLE
  54.  
  55.     BUGS
  56.  
  57.     SEE ALSO
  58.     FreeSignal(), Signal(), Wait()
  59.  
  60.     INTERNALS
  61.  
  62.     HISTORY
  63.  
  64. ******************************************************************************/
  65. {
  66.     AROS_LIBFUNC_INIT
  67.  
  68.     ULONG *mask;
  69.     ULONG mask1;
  70.  
  71.     /* Protect signal mask against possible task exceptions. */
  72.     Forbid();
  73.  
  74.     /* Get pointer to mask of allocated signal */
  75.     mask=&SysBase->ThisTask->tc_SigAlloc;
  76.  
  77.     /* Get signal */
  78.     if(signalNum<0)
  79.     {
  80.     /* Any signal will do. */
  81.  
  82.     /*
  83.      * To get the last nonzero bit in a number I use a&~a+1:
  84.      * Given a number that ends with a row of zeros  xxxx1000
  85.      * I first toggle all bits in that number     XXXX0111
  86.      * then add 1 to toggle all but the last 0 again XXXX1000
  87.      * and AND this with the original number     00001000
  88.      *
  89.      * And since ~a+1=-a I can use a&-a instead.
  90.      *
  91.      * And to get the last zero bit I finally use ~a&-~a.
  92.      */
  93.     mask1=~*mask&-~*mask;
  94.  
  95.     /* Got a bit? */
  96.     if(mask1)
  97.     {
  98.         /* Allocate and reset the bit */
  99.         *mask|=mask1;
  100.         SysBase->ThisTask->tc_SigRecvd&=~mask1;
  101.  
  102.         /* And get the bit number */
  103.         signalNum=(mask1&0xffff0000?16:0)+(mask1&0xff00ff00?8:0)+
  104.               (mask1&0xf0f0f0f0? 4:0)+(mask1&0xcccccccc?2:0)+
  105.               (mask1&0xaaaaaaaa? 1:0);
  106.     }
  107.     }else
  108.     {
  109.     /* Get a specific signal */
  110.     mask1=1<<signalNum;
  111.  
  112.     /* Check if signal is free */
  113.     if(*mask&mask1)
  114.         /* No. Return */
  115.         signalNum=-1;
  116.     else
  117.     {
  118.         /* It is free. Allocate and reset it. */
  119.         *mask|=mask1;
  120.         SysBase->ThisTask->tc_SigRecvd&=~mask1;
  121.     }
  122.     }
  123.  
  124.     Permit();
  125.  
  126.     return signalNum;
  127.     AROS_LIBFUNC_EXIT
  128. }
  129.  
  130.